/*! \file system.h
    \brief Le coeur du jeu, tous ce qui concerne la gestion du system.
    \author Angéline Guignard & Adrien Megueddem
    \copyright Imac Tour Defense
    \language C
    \updated 2013-05-21
*/

#ifndef _ITD__SYSTEM_H___
#define _ITD__SYSTEM_H___

#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL_image.h>
#include "../include/modules/itd.h"
#include "../include/modules/map.h"
#include  <AntTweakBar.h>
#include "../lib/GM/include/list.h"
#include "../include/modules/player.h"
#include "../include/modules/interface.h"

/*! \def EPSILON
    \brief Ce define d'EPSILON permet de faire toutes les comparaisons de float.
*/
#define EPSILON 0.00001

/*! \enum gameState
    \brief Définit le statut du Jeu.
        Cet Enum permet dans la boucle de jeu SDL de savoir dans quel état le jeu se trouve
        et ainsi définir des évènements et des dessins différents selon l'état du programme.
        C'est ce qui nous permet de créer un menu d'entré pour le jeu.
*/
typedef enum gameState{
    MENU,
    GAME,
    WIN,
    LOOSE,
}GameState;

/*! \fn void reshape()
    \brief Definit les paramètre OpenGL.
        Définit le viewPort et l'axe 2D OpenGL.
*/
void reshape();

/*! \fn void setVideoMode(unsigned int w_width, unsigned int w_height)
    \brief Lance ou rafraichit le contexte SDL.
        Cette fonction appelle reshape();
    \param w_width largeur de la fenêtre SDL contenu dans la structure param.
    \param w_height hauteur de la fenêtre SDL contenu dans la structure param.
*/
void setVideoMode(unsigned int w_width, unsigned int w_height);

/*! \fn int ImacTowerDefense()
    \brief Permet d'initialisé toute notre application avec SDL et le contexte OpenGL puis,
        lance le jeu sur son menu d'acceuil afin de choisir un fichier itd, lire les règles ou quitter.
    \result lanceur de l'application.
    \return retourne 1 si l'on veut rejouer, 0 sinon. (mettre une boucle while dans le main avec une variable
        replay pour pouvoir relancer ImacTowerDefense(NULL) tant que la fonction retourne 1.)
*/
int ImacTowerDefense();

/*! \fn Map* init(Player *player, Map *map, char *pathMap, Itd itd, GLuint *textureMap)
    \brief Permet de remplir toutes les variables necessaire au lancement du jeu map, rempli grâce au .itd selectionné dans le menu.
    \result Initialise tout les éléments du jeu.
    \return retourne 1 si tout s'est bien passé.
*/
Map* init(Player *player, Map *map, char *pathMap, Itd itd, GLuint *textureMap);

/*! \fn void idle(Player *player, Map *map, List *listM, List *listT, GLuint *textureMonster, GLuint *textureTower, TwBar **twMonster)
    \brief Permet de gérer toutes les actions et mouvements en continu du jeu,
    \param player
    \param map
    \param listM
    \param listT
    \param textureMonster
    \param textureTower
    \param twMonster
*/
void idle(Player *player, Map *map, List *listM, List *listT, GLuint *textureMonster, GLuint *textureTower, TwBar **twMonster);

/*! \fn void play(int *replay, int *loop, SDL_Event *e, char* pathITD, Tools* tools, MenuITD *menuItd, TwBar **welcomeMenu, TwBar **rulesMenu, TwBar **menu, TwBar **twTower, TwBar **twMonster, TwBar **lastMenu, Itd itd, Player *player, Map *map, List *itds, List *listM, List *listT, GLuint *textureMap, GLuint *textureMonster, GLuint *textureTower, GLuint *textureMenu, GLuint *textureWin, GLuint *textureLoose)
    \brief Permet de lancer la boucle du jeu.
        la boucle de jeu play permet de gérer tout les différents états du jeu comme le menu ou l'état win...
    \param replay
    \param loop
    \param e (evenement SDL_Event)
    \param pathITD
    \param tools
    \param menuItd
    \param welcomeMenu
    \param rulesMenu
    \param menu
    \param twTower
    \param twMonster
    \param lastMenu
    \param itd
    \param player
    \param map
    \param listM
    \param listT
    \param textureMap
    \param textureMonster
    \param textureTower
    \param textureMenu
    \param textureWin
    \param textureLoose
*/
void play(int *replay, int *loop, SDL_Event *e, char* pathITD, Tools* tools, MenuITD *menuItd, TwBar **welcomeMenu, TwBar **rulesMenu, TwBar **menu, TwBar **twTower, TwBar **twMonster, TwBar **lastMenu, Itd itd, Player *player, Map *map, List *itds, List *listM, List *listT, GLuint *textureMap, GLuint *textureMonster, GLuint *textureTower, GLuint *textureMenu, GLuint *textureWin, GLuint *textureLoose);

/*! \fn void resize(int w, int h, Player *player)
    \brief Permet de resizer la fenêtre SDL.
        récupère la taille resize et la réafecte à param contenu dans player.
    \param w
    \param h
    \param player
*/
void resize(int w, int h, Player *player);

/*! \fn int fastForward()
    \brief Permet de changer la vitesse du jeu.
    \result retourne 1 si on est en avance rapide, 0 si on revient en vitesse normale, -1 si il y a une erreur.
*/
int fastForward();

/*! \fn void pause(int *loop)
    \brief Permet de mettre en pause le moteur du jeu (Le jeu peut être quitté à l'intérieur du jeu.
*/  
void pause(int *loop);

/*! \fn List getItds()
    \brief Liste les fichier .itd du dossier /data.
*/  
List getItds();

/*! \fn int exitClean(List *itds, List *listM, List *listT, GLuint *textureMap, GLuint *textureMonster, GLuint *textureTower, GLuint *textureMenu, GLuint *textureWin, GLuint *textureLoose, Player *player, Map *map, TwBar **lastMenu, TwBar **twTower, TwBar **twMonster, TwBar **menu, TwBar **welcomeMenu, TwBar **rulesMenu)
    \brief Permet de quitter proprement le programme en désalouant la mémoire des mallocs.
    \param itds
    \param listM
    \param listT
    \param textureMap
    \param textureMonster
    \param textureTower
    \param textureMenu
    \param textureWin
    \param textureLoose
    \param player
    \param map
    \param lastMenu
    \param twTower
    \param twMonster
    \param menu
    \param welcomeMenu
    \param rulesMenu
    \result Désalou tout les éléments préalablement malloc.
*/
int exitClean(List *itds, List *listM, List *listT, GLuint *textureMap, GLuint *textureMonster, GLuint *textureTower, GLuint *textureMenu, GLuint *textureWin, GLuint *textureLoose, Player *player, Map *map, TwBar **lastMenu, TwBar **twTower, TwBar **twMonster, TwBar **menu, TwBar **welcomeMenu, TwBar **rulesMenu);

/*! \fn quit()
    \param l récupère la loop
    \brief Permet de quitter le jeu.
*/
void quit(int *l);

#endif